﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

// Nice link to use for creating software
// http://www.netrunneronline.com/set/classic/cards/
// and
// http://chimericalchain.hubpages.com/hub/The-Game-Graveyard-Remembering-the-Netrunner-CCG

//http://www.netrunneronline.com/rules/?s=1
//http://www.netrunneronline.com/cards/black-dahlia/

///During a run, there are three stages in dealing with a piece of ice. First, you are approaching that piece of ice. 
///If that piece of ice is not already rezzed, the Corp can rez it at this point. The Corp can only rez a piece of ice 
///when you are approaching it. If that piece of ice is rezzed or was already rezzed, you encounter it, at which point you 
///can break its subroutines, that is, prevent them from taking effect. If the ice is not rezzed, or if you break all 
///of the subroutines that end your run, you pass that piece of ice. You can then choose either to approach the next 
///piece of ice, or to jack out, which means to voluntarily end the run. This is the only time you can jack out.
///Each piece of ice you encounter will have one or more subroutines on it. Each subroutine will take effect unless you break it. 
///To break an ice subroutine, you need a particular kind of program in play called an icebreaker. Each icebreaker affects 
///whatever keyword categories of ice it references (there are three primary types of ice: walls, code gates, and sentries), 
///but you won't know what kind of icebreaker you'll need to break a piece of ice until that ice is rezzed or revealed. 
///An icebreaker can only break subroutines on a piece of ice if its strength (located in the icon on the lower right corner 
///of the icebreaker) equals or exceeds the ice's strength (located in the icon on the lower left corner of the ice, or lower 
///right if the card is viewed on its side). If the icebreaker is strong enough, you may use it to break one or more subroutines
///of the ice encountered, paying the stated cost for each subroutine you break. Most icebreakers allow you to increase 
///their strength. If you increase an icebreaker's strength, the increase ends when you finish encountering that piece of ice. 
///Usually a single icebreaker is used to break all the subroutines of a given piece of ice, but you may break each subroutine 
///with a different icebreaker.
///If you don't break all of the subroutines of a piece of ice, you suffer the effect of each of the unbroken subroutines, 
///in the order they appear on the card. A subroutine that ends the run does so immediately, and any following subroutines 
///do not take effect. If a subroutine requires a trace attempt (see Traces), make that trace attempt when the subroutine takes 
///effect. If none of the unbroken subroutines end the run, you pass that piece of ice.
///If you pass all the ice on a fort, you have one more opportunity to jack out before the Corp decides whether to rez 
///any nodes or upgrades. If you choose not to jack out at this time, your run is considered successful.

namespace CorporationWars
{
    public delegate void SoftwareAction(Game1 Game, Software software, object target);

    [Serializable]
    public class SoftwareAtributes
    {
        public float HDDSpace { get; set; }           // Storage Space
        public float RAMSpace { get; set; }           // Runtime Space
        public float THtz { get; set; }               // Run Speed (initialtive)
        public float Visibility { get; set; }       // How loud/visible it is.
    }

    [Serializable]
    public class Software : BaseObject
    {
        public string Name { get; set; }
        public string ShortName { get; set; }
        public decimal Cost { get; set; }
        public string Description { get; set; }
        public string TextureAsset { get; set; }

        public object RenderData { get; set; }

        public SoftwareAtributes Attributes { get; set; }
        public List<SoftwareAction> Actions { get; set; }

        public Software(Game1 game) : base(game) 
        {
            Name = ID;
            Attributes = new SoftwareAtributes();
            Actions = new List<SoftwareAction>();
        }

        public static Software CreateSoftware(Game1 game, string name, string shortName, decimal cost, string description, string textureAsset, SoftwareAtributes attributes, List<SoftwareAction> actions)
        {
            return new Software(game) { Name = name, ShortName = shortName, Description = description, TextureAsset = textureAsset, Attributes = attributes, Actions = actions };
        }

        public void RunMyActions(object target)
        {
            foreach (SoftwareAction sa in Actions)
            {
                sa(Game, this, target);
            }
        }

        public static Software CreateBasicFirewall(Game1 game)
        {
            SoftwareAtributes atribs = new SoftwareAtributes();
            atribs.HDDSpace = 1;
            atribs.RAMSpace = .5f;
            atribs.THtz = 1;
            atribs.Visibility = 1f;
            return CreateSoftware(game, "Basic Firewall", "Firewall", 250, "The base of all node security, the firewall.", "Textures/Software/BaseFireWall", atribs, null);
        }

        public void DeleteSoftware()
        {
            Attributes = null;

            Actions.Clear();
            Actions = null;
        }
    }
}
